Proyecto Individual CA0204 - Herramientas De Ciencias De Datos I
Mapa de accidentes de transito por canton en Costa Rica 2018-2023
Author
Randal Picado Bermúdez C36024
Published
November 1, 2025
Cargar librerias
library(readr)library(dplyr)
Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
library(ggplot2)library(geodata)
Cargando paquete requerido: terra
terra 1.8.70
library(leaflet)library(sf)
Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(htmlwidgets)
Cargar bases de datos
#Se cargan las bases de datos extraidas de COSEVI.accidentes.personas <-read_delim("3 Base de personas en accidentes 2017_ 2023_UTF8.csv", delim =";", escape_double =FALSE, trim_ws =TRUE)
Rows: 223050 Columns: 12
── Column specification ────────────────────────────────────────────────────────
Delimiter: ";"
chr (11): Rol, Tipo de lesión, Edad, Sexo, Vehiculo en el que viajaba, Prov...
dbl (1): Año
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
accidentes <-read_delim("2 Base de accidentes con victimas 2018_ 2024_UTF8.csv", delim =";", escape_double =FALSE, trim_ws =TRUE)
Rows: 104898 Columns: 21
── Column specification ────────────────────────────────────────────────────────
Delimiter: ";"
chr (20): Clase de accidente, Tipo de accidente, Hora, Hora recodificada, Pr...
dbl (1): Año
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#Se filtran ambas bases en años que coincidan, en los periodos del 2018-2023accidentes.personas.2018.2023<- accidentes.personas %>%filter(Año >=2018& Año <=2023)accidentes.2018.2023<- accidentes %>%filter(Año >=2018& Año <=2023 )
##Manipulacion de las bases
personas.moto <- accidentes.personas.2018.2023%>%filter( `Vehiculo en el que viajaba`=="Motocicleta") %>%mutate(Edad =as.numeric(Edad) )
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `Edad = as.numeric(Edad)`.
Caused by warning:
! NAs introducidos por coerción
#Ver datos por cantondatos.canton <- personas.moto %>%group_by(Provincia, Cantón) %>%summarise(Total.motociclistas =n(),Total.ilesos =sum(`Tipo de lesión`=="Ileso"),Total.leves =sum(`Tipo de lesión`=="Herido leve"),Total.graves =sum(`Tipo de lesión`=="Herido grave"),Total.fallecidos =sum(`Tipo de lesión`=="Muerte"),Tasa.gravedad = (Total.graves + Total.fallecidos) / Total.motociclistas *100,Total.hombres =sum(Sexo =="Hombre"),Total.mujeres =sum(Sexo =="Mujer"),Promedio.edad =mean(Edad, na.rm =TRUE),Jovenes.18.25 =sum(Edad >=18& Edad <=25, na.rm =TRUE),Adulto.mayores =sum(Edad>60, na.rm =TRUE),.groups ="drop" )#De la base accidentesaccidentes.canton <- accidentes.2018.2023%>%filter(`Tipo de accidente`=="Colisión con motocicleta") %>%group_by(Provincia, Cantón) %>%summarise(Total.accidentes.moto =n(),Porcentaje.curvas = (sum(`Calzada horizontal`=="Curva", na.rm =TRUE) / Total.accidentes.moto) *100,Porcentaje.lluvia = (sum(`Estado del tiempo`=="Lluvia", na.rm =TRUE) / Total.accidentes.moto) *100,.groups ="drop" )#Unir las bases datos.completos.canton <- datos.canton %>%full_join(accidentes.canton, by =c("Provincia", "Cantón")) %>%mutate( Cantón =case_when( Cantón =="León Cortés"~"León Cortés Castro", Cantón =="Valverde Vega"~"Sarchí",TRUE~ Cantón ) )#Se cambio los nombres de dos cantones para que coincidan con los de cr.cantones.sf
Creacion del mapa
#Obtener los limites por cantones (nivel 2)cr.cantones <-gadm(country ="CRI", level =2, path =tempdir())#Combertir para mejor manipulacióncr.cantones.sf <-st_as_sf(cr.cantones)#Unir con los datos de cada canton datos.canton.geo <- cr.cantones.sf %>%left_join(datos.completos.canton, by =c("NAME_2"="Cantón"))#Crear categorías por cantidad de motociclistas en accidentesdatos.canton.geo <- datos.canton.geo %>%mutate(categoria.motociclistas =case_when( Total.motociclistas <500~"Menos de 500", Total.motociclistas >=500& Total.motociclistas <1000~"500 - 999", Total.motociclistas >=1000& Total.motociclistas <2000~"1,000 - 1,999", Total.motociclistas >=2000~"2,000 o más" ),categoria.motociclistas =factor(categoria.motociclistas,levels =c("2,000 o más", "1,000 - 1,999", "500 - 999", "Menos de 500")) )#leyenda, con paleta de colores colores.motociclistas <-c("2,000 o más"="#993404" ,"1,000 - 1,999"="#d95f0e" ,"500 - 999"="#fec44f","Menos de 500"="#D1BC1B")pal <-colorFactor(colores.motociclistas, domain = datos.canton.geo$categoria.motociclistas)#crear mapamapa.cantones <-leaflet(datos.canton.geo) %>%addTiles() %>%addPolygons(fillColor =~pal(categoria.motociclistas),fillOpacity =0.7,color ="Black",weight =1,opacity =0.8,smoothFactor =1,label =~NAME_2,labelOptions =labelOptions(),highlightOptions =highlightOptions(weight =3,color ="Black",fillOpacity =0.9,bringToFront =TRUE ),#El popup es el cuadrito que se muestra al seleccionar un cantonpopup =~paste(#Contenedor principal"<div style = 'max-width: 260px; font-family: Arial;'>",#Encabezado"<h3>", NAME_2, "</h3>","<p><b>Provincia:</b> ", NAME_1, "</p>","<hr>","<h4>Estadisticas Principales:</h4>","<p><b>• Total Accidentes:</b> ", Total.accidentes.moto, "</p>","<p><b>• Total motociclistas:</b> ", Total.motociclistas, "</p>","<p><b>• Tasa gravedad:</b> ", round(Tasa.gravedad,0), "%</p>","<p><b>• Edad promedio:</b> ", round(Promedio.edad,0), " años</p>","<hr>","<h4>Factores de Riesgo:</h4>","<p><b>• Curvas:</b> ", round(Porcentaje.curvas, 0), "%</p>","<p><b>• Lluvia:</b> ", round(Porcentaje.lluvia, 0), "%</p>","<p><b>• Jovenes 18-25 años:</b> ", Jovenes.18.25, "</p>","<hr>","<h4>Consecuencias:</h4>","<p><b>• Fallecidos:</b> ", Total.fallecidos, "</p>","<p><b>• Heridos graves:</b> ", Total.graves, "</p>","<p><b>• Heridos leves:</b> ", Total.leves, "</p>","<p><b>• Ilesos:</b> ", Total.ilesos, "</p>","</div>" ) ) %>%addLegend(position ="bottomright",pal = pal,values =~categoria.motociclistas,title ="Motociclistas<br>Accidentados",opacity =0.8 ) %>%addControl(html ="<div style='background: white; padding: 8px; border: 2px solid #993404; font-weight: bold; font-size: 14px; color: #993404; '>Accidentes de Motociclistas por Cantón</div>",position ="topright" ) %>%setView(lng =-84.2, lat =9.6, zoom =7)mapa.cantones
#Guaradar en htmlsaveWidget(mapa.cantones, "mapa.cantones.html", selfcontained =TRUE)browseURL("mapa.cantones.html")